#pragma once
#include "dx11_mesh.h"

struct FRAME_PARAMS
{
	// camera
	D3DXMATRIX m_mWorld;
	D3DXMATRIX m_mView;
	D3DXMATRIX	m_mProj;

	D3DXVECTOR3 m_vEye;
	D3DXVECTOR3 m_vLookAt;

	float		m_fvFOV;

	// lighting
	D3DXVECTOR4 m_vAmbientLightColor;

	D3DXVECTOR4 m_vPointLightPos;
	D3DXVECTOR4 m_vPointLightColor;
};

class CSceneRenderer
{
private:
	void CreateShaderAndLayout(ID3D11Device* pd3dDevice);
	void CreateConstantBuffers(ID3D11Device* pd3dDevice);
	void CreateSamplerStates(ID3D11Device* pd3dDevice);
	
	void SetSamplerStates(ID3D11DeviceContext* pd3dContext);
	void SetConstantBuffer(ID3D11DeviceContext* pd3dContext, FRAME_PARAMS& frameParams);

    // function for render a single mesh
	void RenderDX11Mesh(ID3D11DeviceContext* pd3dContext, CDX11Mesh* pMesh);
    // function for render n meshes, compared to call RenderDX11Mesh() n times, this function
    // saves some shader setting
    void RenderSceneMeshes(ID3D11DeviceContext* pd3dContext, vector<CDX11Mesh*>& sceneMeshes);
    void CalcBoundBox();

public:
	CSceneRenderer(void);
	~CSceneRenderer(void);

	void OnCreateDevice(ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dContext);
    void OnFrameRender(ID3D11DeviceContext* pd3dContext, FRAME_PARAMS& frameParams);
	void OnDestroy();

private:
	vector<CDX11Mesh*>		    m_SceneObjects;
    D3DXVECTOR3                 m_BBMax;
    D3DXVECTOR3                 m_BBMin;
	///////////////////////////////////////////////////////////////////////
	// Shader 
	// Render scene objects with phong shading
	ID3D11VertexShader*			m_pVSScene;
	ID3D11PixelShader*			m_pPSScene;
	
	ID3D11InputLayout*			m_pLayoutScene;

    // constant buffer
    ID3D11Buffer*				m_pcbMatObj;
    ID3D11Buffer*				m_pcbPerFrame;

    // sampler states
	ID3D11SamplerState*			m_pSamplerStateLinearWrap ;
	ID3D11SamplerState*			m_pSamplerStateLinearClamp ;
	ID3D11SamplerState*			m_pSamplerStatePointClamp ;
	ID3D11SamplerState*			m_pSamplerStateCmpLess;
};
